﻿Imports Mystery

''' <summary>
''' handle global interface request and pointer
''' </summary>
''' <remarks></remarks>
<GlobalAvalibleObjectImplementation(singleton:=True)>
Public Class InterfaceStatus

    Private Sub DropContent(content As IContent)
        For Each c As IContentShower In _content_controls
            Dim loop_var As IContentShower = c
            _Dispatcher.Invoke(Sub()
                                   Try
                                       loop_var.DropContent(content)
                                   Catch ex As Exception

                                   End Try
                               End Sub)
        Next
    End Sub

    Public Sub New()
        Dim cd As IContentDispatcher = getGlobalObject(Of IContentDispatcher)()
        AddHandler cd.contentRemoved, AddressOf DropContent
    End Sub

    Dim _Dispatcher As System.Windows.Threading.Dispatcher = System.Windows.Threading.Dispatcher.CurrentDispatcher

    Private _type_control As New HashSet(Of ITypeShower)

    Public Sub registerTypeShow(control As ITypeShower)
        _type_control.Add(control)
    End Sub


    Public Event statusChanged()
    Private _showen_type As Type

    Public Property showen_type As Type
        Get
            Return _showen_type
        End Get
        Set(value As Type)
            If value = _showen_type Then Exit Property
            _showen_type = value
            RaiseEvent statusChanged()
        End Set
    End Property

    Private _showen_content As IContent

    Public Property showen_content As IContent
        Get
            Return _showen_content
        End Get
        Set(value As IContent)
            If value Is Nothing AndAlso _showen_content Is Nothing Then Exit Property
            If _showen_content IsNot Nothing AndAlso _showen_content.Equals(value) Then Exit Property
            _showen_content = value
            RaiseEvent statusChanged()
        End Set
    End Property


    Public Function showType(content_type As Type, force_reload As Boolean) As Boolean
        If content_type = _showen_type AndAlso Not force_reload Then Return True
        For Each c As ITypeShower In _type_control
            If c.show(content_type) Then Return True
        Next
        Return False
    End Function

    Private _type_add As New HashSet(Of IContentCreatorControl)

    Public Sub registerTypeAdd(control As IContentCreatorControl)
        _type_add.Add(control)
    End Sub

    ''' <summary>
    ''' create a type, you can actually pass the content so it is to complete
    ''' </summary>
    ''' <param name="type"></param>
    ''' <param name="content">if nothing a new will be created</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function addType(type As Type, content As IContent) As IContentCreatorControl
        For Each c As IContentCreatorControl In _type_add
            If c.canDo(type) AndAlso c.setUp(type, content) Then
                Return c
            End If
        Next
        Return Nothing
    End Function

    Private _content_controls As New HashSet(Of IContentShower)

    Public Sub registerContentShow(control As IContentShower)
        _content_controls.Add(control)
    End Sub

    Public Sub deregisterContentShow(control As IContentShower)
        _content_controls.Remove(control)
    End Sub


    Private Sub createWindowForContent(content As IContent)
        'none of the current control what show this guys, fine let's make it pop up
        Dim new_window As New Window
        Dim mystery_new_window As INewWindow = getGlobalObject(Of INewWindow)()
        Dim reftext As ReferenceText = content.GetType().getFirstAttribute(Of ReferenceText)()
        Dim title As String = mystery_new_window.getTitle
        If reftext IsNot Nothing Then
            title = title & " " & reftext.getReferenceText(content)
        Else
            title = title & " " & content.guid.ToString
        End If
        new_window.Title = title

        Dim cva As ContentViewAttribute = content.GetType.getMysteryAttribute(Of ContentViewAttribute)()
        Dim content_view As UserControl = cva.createControl(content)
        new_window.Height = cva.new_window_height
        new_window.Width = cva.new_window_width

        new_window.Content = content_view
        new_window.Show()
        new_window.Focus()
        showen_content = content
        AddHandler new_window.Activated, Sub()
                                             showen_content = content
                                         End Sub
        If TypeOf (content_view) Is IContentShower Then
            Me.registerContentShow(content_view)
            AddHandler new_window.Closed, Sub()
                                              _content_controls.Remove(content_view)
                                              _showen_content = Nothing
                                          End Sub
        End If

    End Sub

    ''' <summary>
    ''' show get content
    ''' </summary>
    ''' <param name="content">content to show</param>
    ''' <param name="it_has_changed_values">set true when the content have change values, so then current showing controls must refresh</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function showContent(content As IContent, it_has_changed_values As Boolean) As Boolean


        If content Is Nothing Then Return False
        If content.Equals(_showen_content) AndAlso Not it_has_changed_values Then Return True

        For Each c As IContentShower In _content_controls
            Dim result As Boolean
            Dim shower As IContentShower = c
            _Dispatcher.Invoke(Sub()
                                   Try
                                       result = shower.show(content)
                                   Catch ex As Exception

                                   End Try
                               End Sub)
            If result Then Return True
        Next

        _Dispatcher.Invoke(Sub() createWindowForContent(content))


        Return True
    End Function

End Class
